home *** CD-ROM | disk | FTP | other *** search
/ The Fatted Calf / The Fatted Calf.iso / Applications / Games / Chess / Source / Board.m < prev    next >
Text File  |  1994-04-01  |  9KB  |  359 lines

  1. #import <appkit/appkit.h>
  2.  
  3. #import "chess_strings.h"
  4. #import "Chess.h"
  5. #import "gnuchess.h"
  6. #import "Board.h"
  7. #import "Square.h"
  8.  
  9. @implementation Board
  10.  
  11. #define BLACK_SQUARE_COLOR  0.5
  12. #define WHITE_SQUARE_COLOR  (5.0/6.0)
  13.  
  14. + newFrame: (const NXRect *)f
  15. {
  16.   int r, c;
  17.   
  18.   self = [super newFrame: f];
  19.   [self allocateGState];
  20.   backBitmap = [Bitmap newSize: f->size.width / 8.0 
  21.           : f->size.height / 8.0 type: NX_UNIQUEBITMAP];
  22.   [backBitmap setFlip: YES];
  23.   for( r = 0; r < 8; r++ )
  24.     for( c = 0; c < 8; c++ ){
  25.       square[r][c] = [Square new];
  26.       [square[r][c] setBackground: (r+c)%2 == 0 ? BLACK_SQUARE_COLOR : WHITE_SQUARE_COLOR];
  27.     }
  28.   [self setupPieces];
  29.   return self;
  30. }
  31.  
  32. - setupPieces
  33. {
  34.   [self layoutBoard: Stboard color:Stcolor];
  35. }
  36.  
  37. - layoutBoard: (short *)b color: (short *)c
  38. {
  39.   int sq, row, col;
  40.   
  41.   for (sq = 0; sq < 64; sq++){
  42.     row = sq / 8;
  43.     col = sq % 8;
  44.     switch( b[sq] ){
  45.     case pawn:
  46.       [self placePiece: c[sq]==white?WHITE_PAWN:BLACK_PAWN at: row: col];
  47.       break;
  48.     case rook:
  49.       [self placePiece: c[sq]==white?WHITE_ROOK:BLACK_ROOK at: row: col];
  50.       break;
  51.     case knight:
  52.       [self placePiece: c[sq]==white?WHITE_KNIGHT:BLACK_KNIGHT at: row: col];
  53.       break;
  54.     case bishop:
  55.       [self placePiece: c[sq]==white?WHITE_BISHOP:BLACK_BISHOP at: row: col];
  56.       break;
  57.     case king:
  58.       [self placePiece: c[sq]==white?WHITE_KING:BLACK_KING at: row: col];
  59.       break;
  60.     case queen:
  61.       [self placePiece: c[sq]==white?WHITE_QUEEN:BLACK_QUEEN at: row: col];
  62.       break;
  63.     default:
  64.       [self placePiece: 0 at: row: col];
  65.       break;
  66.     }
  67.   }
  68. }
  69.  
  70. - slidePieceFrom: (int)r1 : (int)c1 to: (int)r2 : (int)c2
  71. {
  72.   NXPoint p, backP, endP;
  73.   NXRect pieceRect;
  74.   int controlGState, i, increments;
  75.   char const *icon;
  76.   NXCoord incX, incY;
  77.   
  78.   
  79.   icon = [square[r1][c1] icon];
  80.   if( !icon )
  81.     return self;
  82.     
  83.   controlGState = [self gState];
  84.   pieceRect.size.width = floor( frame.size.width / 8.0 );
  85.   pieceRect.size.height = floor( frame.size.height / 8.0 );
  86.   backP.x = (((float)c1) * pieceRect.size.width);
  87.   backP.y = (((float)r1) * pieceRect.size.height);
  88.   endP.x = (((float)c2) * pieceRect.size.width);
  89.   endP.y = (((float)r2) * pieceRect.size.height);
  90.  
  91.   [self lockFocus];
  92.   PSgsave();
  93.     
  94.   /* Draw over the piece we are moving. */
  95.   pieceRect.origin.x = c1 * pieceRect.size.width;
  96.   pieceRect.origin.y = r1 * pieceRect.size.height;
  97.   [square[r1][c1] drawBackground: &pieceRect inView: self];
  98.   
  99.   /* Save background */ 
  100.   [backBitmap lockFocus];
  101.   PSgsave();
  102.   PScomposite( backP.x, backP.y, pieceRect.size.width, pieceRect.size.height,
  103.            controlGState, 0.0, pieceRect.size.height, NX_COPY);
  104.   PSgrestore();
  105.   [backBitmap unlockFocus];
  106.   
  107.   incX = endP.x - backP.x;
  108.   incY = endP.y - backP.y;
  109.   increments = (int) MAX( ABS(incX), ABS(incY) ) / 7;
  110.   incX = incX / increments;
  111.   incY = incY / increments;
  112.   for( i = 0; i < increments - 1; i++ ){
  113.  
  114.     /* Restore old background */
  115.     [self lockFocus];
  116.     [backBitmap composite:NX_COPY toPoint: &backP];
  117.     [self unlockFocus];
  118.  
  119.     /* Save new background */
  120.     backP.x += incX;
  121.     backP.y += incY;
  122.     backP.x = floor( backP.x );
  123.     backP.y = floor( backP.y );
  124.     pieceRect.origin = backP;
  125.  
  126.     [backBitmap lockFocus];
  127.     // PSgsave();
  128.     PScomposite( backP.x, backP.y,
  129.          pieceRect.size.width, pieceRect.size.height,
  130.          controlGState, 0.0, pieceRect.size.height, NX_COPY);
  131.     // PSgrestore();
  132.     [backBitmap unlockFocus];
  133.  
  134.     /* Draw piece at new location. */
  135.     [square[r1][c1] drawInside: &pieceRect inView: self];
  136.  
  137.     PSsetgray( NX_BLACK );
  138.     PSsetlinewidth( 2.0 );
  139.     PSclippath();
  140.     PSstroke();
  141.  
  142.     PSflushgraphics();
  143.     NXPing();
  144.   }
  145.  
  146.   PSgrestore();
  147.   [self unlockFocus];
  148. }
  149.  
  150.  
  151. - placePiece: (const char *)p at: (int)r : (int)c
  152. {
  153.   [square[r][c] setIcon: p];
  154. }
  155.  
  156.  
  157. - (int)typeAt: (int)r : (int)c
  158. {
  159.   return( [square[r][c] type] );
  160. }
  161.   
  162. - highlightSquareAt: (int)r : (int) c
  163. {
  164.   NXRect cr;
  165.   
  166.   [self lockFocus];
  167.   cr.size.width = frame.size.width / 8;
  168.   cr.size.height = frame.size.height / 8;
  169.   cr.origin.x = c * cr.size.width;
  170.   cr.origin.y = r * cr.size.height;
  171.   
  172.   [square[r][c] highlight: &cr inView: self];
  173.  
  174.   PSsetgray( NX_BLACK );
  175.   PSsetlinewidth( 2.0 );
  176.   PSclippath();
  177.   PSstroke();
  178.   PSflushgraphics();
  179.   NXPing();
  180.   [self unlockFocus];
  181. }
  182.     
  183. - flashSquareAt: (int)r : (int) c
  184. {
  185. }
  186.  
  187.  
  188.  
  189. - printPSCode: sender
  190. {
  191.   id pi = [NXApp printInfo];
  192.   const NXRect *pr;
  193.   NXCoord lm, rm, tm, bm;
  194.   
  195.   pr = [pi paperRect];
  196.   lm = rm = (pr->size.width - frame.size.width) / 2.0;
  197.   tm = bm = (pr->size.height - frame.size.height) / 2.0;
  198.   [pi setMarginLeft: lm right: rm top: tm bottom: bm];
  199.   
  200.   [self lockFocus];
  201.   NXSizeBitmap( &bounds, &print_size, &print_pwide, &print_phigh,
  202.                 &print_bps, &print_ssp, &print_config, &print_mask );
  203.   print_image = (void *)malloc( print_size );
  204.   NXReadBitmap( &bounds, print_pwide, print_phigh, print_bps, print_ssp,
  205.            print_config, print_mask, print_image, 0, 0, 0, 0 );
  206.   [super printPSCode: self];
  207.   free( print_image );
  208.   [self unlockFocus];
  209.   return self;
  210. }
  211.  
  212. - drawSelf:(const NXRect *)f :(int)rectCount;
  213. {
  214.   int r, c;
  215.   NXRect cr;
  216.   
  217.   if( NXDrawingStatus == NX_DRAWING ){
  218.     PSgsave();
  219.     cr.size.width = f->size.width / 8;
  220.     cr.size.height = f->size.height / 8;
  221.     for( r = 0; r < 8; r++ ){
  222.       cr.origin.y = r * cr.size.height;
  223.       for( c = 0; c < 8; c++ ){
  224.     cr.origin.x = c * cr.size.width;
  225.     [square[r][c] drawSelf: &cr inView: self];
  226.       }
  227.     }
  228.   
  229.     PSsetgray( NX_BLACK );
  230.     PSsetlinewidth( 2.0 );
  231.     PSclippath();
  232.     PSstroke();
  233.     PSgrestore();
  234.   }
  235.   else{
  236.     NXImageBitmap( &bounds, print_pwide, print_phigh, print_bps, print_ssp,
  237.                    print_config, print_mask, print_image, 0, 0, 0, 0 );
  238.   }
  239. }
  240.  
  241. - mouseDown: (NXEvent *)event
  242. {
  243.   NXPoint p, pickedP, backP;
  244.   NXHandler handler;
  245.   NXRect pieceRect, backR;
  246.   int r, c, r2, c2, mask, controlGState, ok;
  247.   char const *icon;
  248.   char *move, *pt;
  249.   unsigned short mv;
  250.   
  251.   
  252.   if( [NXApp finished] ){
  253.     [NXApp finishedAlert];
  254.     handler.code = 0;
  255.     [window addToEventMask: NX_MOUSEUPMASK|NX_MOUSEDRAGGEDMASK];
  256.     NX_DURING
  257.       while (event->type != NX_MOUSEUP){
  258.     event = [NXApp getNextEvent:NX_MOUSEUPMASK|NX_MOUSEDRAGGEDMASK];
  259.       }
  260.     NX_HANDLER
  261.       handler = NXLocalHandler;
  262.     NX_ENDHANDLER
  263.     return self;
  264.   }
  265.   
  266.   pickedP = event->location;
  267.   [self convertPoint:&pickedP fromView:nil];
  268.   backP = pickedP;
  269.   r = (int) floor( pickedP.y / (frame.size.height / 8.0 )); 
  270.   c = (int) floor( pickedP.x / (frame.size.width / 8.0 ));
  271.   icon = [square[r][c] icon];
  272.   backR.size.width = pieceRect.size.width = floor( frame.size.width / 8.0 );
  273.   backR.size.height = pieceRect.size.height = floor( frame.size.height / 8.0 );
  274.   backR.origin.x = backR.origin.y = 0;
  275.   pickedP.x = pickedP.x - (((float)c) * pieceRect.size.width);
  276.   pickedP.y = pickedP.y - (((float)r) * pieceRect.size.height);
  277.   if( icon && [self isEnabled] ){
  278.     controlGState = [self gState];
  279.     if( !controlGState ){
  280.       [self allocateGState];
  281.       controlGState = [self gState];
  282.     }
  283.     [self lockFocus];
  284.     
  285.     PSgsave();
  286.     /* Draw over the piece we are moving. */
  287.     pieceRect.origin.x = c * pieceRect.size.width;
  288.     pieceRect.origin.y = r * pieceRect.size.height;
  289.     [square[r][c] drawBackground: &pieceRect inView: self];
  290.     
  291.     /* Save background */ 
  292.     [backBitmap lockFocus];
  293.     PSgsave();
  294.     PScomposite( backP.x, backP.y, backR.size.width, backR.size.height,
  295.          controlGState, 0.0, backR.size.height, NX_COPY);
  296.     PSgrestore();
  297.     [backBitmap unlockFocus];
  298.   } 
  299.     
  300.   handler.code = 0;
  301.   [window addToEventMask: NX_MOUSEUPMASK|NX_MOUSEDRAGGEDMASK];
  302.   NX_DURING
  303.     while (event->type != NX_MOUSEUP){
  304.       event = [NXApp getNextEvent:NX_MOUSEUPMASK|NX_MOUSEDRAGGEDMASK];
  305.       p = event->location;
  306.       [self convertPoint:&p fromView:nil];
  307.       if( icon && [self isEnabled] ){
  308.         /* Restore old background */
  309.     [self lockFocus];
  310.     [backBitmap composite:NX_COPY toPoint: &backP];
  311.     [self unlockFocus];
  312.     
  313.     /* Save new background */
  314.     backP.x = pieceRect.origin.x = p.x - pickedP.x;
  315.     backP.y = pieceRect.origin.y = p.y - pickedP.y;
  316.     [backBitmap lockFocus];
  317.     PSgsave();
  318.     PScomposite( backP.x, backP.y,
  319.              backR.size.width, backR.size.height,
  320.              controlGState, 0.0, backR.size.height, NX_COPY);
  321.     PSgrestore();
  322.     [backBitmap unlockFocus];
  323.     
  324.     /* Draw piece at new location. */
  325.     [square[r][c] drawInside: &pieceRect inView: self];
  326.  
  327.     PSsetgray( NX_BLACK );
  328.     PSsetlinewidth( 2.0 );
  329.     PSclippath();
  330.     PSstroke();
  331.  
  332.     PSflushgraphics();
  333.     NXPing();
  334.       }
  335.     }
  336.   NX_HANDLER
  337.     handler = NXLocalHandler;
  338.   NX_ENDHANDLER
  339.   
  340.   if( icon && [self isEnabled] ){
  341.     r2 = (int) floor( p.y / (frame.size.height / 8.0 )); 
  342.     c2 = (int) floor( p.x / (frame.size.width / 8.0 ));
  343.     if( r2 != r || c2 != c ){
  344.       if( ![NXApp makeMoveFrom: r : c to: r2 : c2] ){
  345.         [self display];
  346.     NXPing();
  347.       }
  348.     }
  349.     PSgrestore();
  350.     [self unlockFocus];
  351.   }
  352.  
  353.   if (handler.code) {
  354.     NX_RAISE(handler.code, handler.data1, handler.data2);
  355.   }
  356. }
  357.  
  358. @end
  359.